package com.acegear.horizon.domain.repository;

import com.acegear.horizon.domain.models.ClubEvent;
import com.acegear.horizon.domain.models.constraint.ClubEventState;
import com.acegear.horizon.domain.models.constraint.ClubEventType;
import com.acegear.horizon.domain.repository.jpa.ClubEventBaseRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

import javax.persistence.criteria.Predicate;

/**
 * Created by wangsike on 2017/1/9.
 */
@Component
public class ClubEventRepository {

    @Autowired
    private ClubEventBaseRepository clubEventBaseRepository;

    public Optional<ClubEvent> findByEventId(Long eventId) {
        return clubEventBaseRepository
                .findByClubEventId(eventId)
                .map(ClubEvent::new);
    }

    public Stream<ClubEvent> findByClubId(Long clubId, ClubEventState eventState, Pageable pageable) {
        return clubEventBaseRepository
                .findByOwnerIdAndState(clubId, eventState, pageable)
                .stream()
                .map(ClubEvent::new);
    }
    
    /**
     * 
     * @param clubId
     * @param eventState 如果未空代码查询全部
     * @param startAt 如果未空代码查询全部
     * @param endAt 如果未空代码查询全部
     * @param pageable
     * @return
     */
    public Stream<ClubEvent> findByClubId(Long clubId, ClubEventState eventState, Long startAt, Long endAt, Pageable pageable) {
        return clubEventBaseRepository
                .findByOwnerIdAndState(clubId, eventState, pageable)
                .stream()
                .map(ClubEvent::new);
    }

    public Stream<ClubEvent> queryEvent(Long clubId, ClubEventType eventType, ClubEventState eventState, Pageable pageable) {
        return clubEventBaseRepository
                .findAll((root, cq, cb) -> {
                    List<Predicate> list = new ArrayList<>();
                    list.add(cb.equal(root.get("deleted"), false));
                    if (clubId != null) {
                        list.add(cb.equal(root.get("ownerId"), clubId));
                    }
                    if (eventType != null) {
                        list.add(cb.equal(root.get("type"), eventType));
                    }
                    if (eventState != null) {
                        list.add(cb.equal(root.get("state"), eventState));
                    }
                    Predicate[] predicates = new Predicate[list.size()];
                    cq.where(cb.and(list.toArray(predicates)));
                    cq.orderBy(cb.asc(root.get("state")), cb.asc(root.get("startAt")));
                    return cq.getRestriction();
                }, pageable)
                .getContent()
                .stream()
                .map(ClubEvent::new);
    }

    public Stream<ClubEvent> findByEventIds(List<Long> eventIds) {
        return clubEventBaseRepository
                .findByClubEventIds(eventIds)
                .stream()
                .map(ClubEvent::new);
    }
}
